﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;

using DotSpatial.Topology;

using System.Windows.Forms;

using Point = System.Drawing.Point;

using System.Drawing.Drawing2D;




namespace FXnaGis
{


    public enum FSimpleGemotryEditMode
    {
        POINT,
        LINE,
        POLY
    }


    /// <summary>
    /// 设计用于实现简单的 点 ，线 ，面 的添加操作
    /// 基于vectorlayer
    /// </summary>
    public class FSimpleGeometryEditMF:FAddGeometryMF
    {


        #region events

        public event EventHandler AskAddGeometry;


        #endregion

        public FSimpleGeometryEditMF(FMapFrame frame)
            : base(frame)
        {


 

        }


        FSimpleGemotryEditMode _mode;

        public FSimpleGemotryEditMode Mode
        {
            get { return _mode; }
            set { _mode = value; }
        }


        private List<Coordinate> _coordinates = new List<Coordinate>();

        /// <summary>
        /// 这里我们把他设计为对外的数据暂存接口
        /// 外部通过它来获得具体的坐标值
        /// </summary>
        public List<Coordinate> Coordinates
        {
            get { return _coordinates; }


        }




        protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseUp(e);


            if (e.Button == MouseButtons.Left)
            {

                Coordinate c = this._geoMapFrame.BufferToProj(e.Location); ;

                switch (this._mode)
                {


                    case FSimpleGemotryEditMode.POINT:

                        this._coordinates.Clear();


                        this._coordinates.Add(c);

                        this.AddGeomotry();







                        break;
                    case FSimpleGemotryEditMode.LINE:




                        //这里需要加入判断逻辑，

                        this._coordsInner.Add(c);

                      

                      









                        break;
                    case FSimpleGemotryEditMode.POLY:


                      

                        this._coordsInner.Add(c);




                        break;
                    default:
                        break;
                }



            }

            if (e.Button == MouseButtons.Right)
            {

                if (this._mode == FSimpleGemotryEditMode.LINE)
                {


                    this.FinishLine();

                }


                if (this._mode==FSimpleGemotryEditMode.POLY)
                {

                    this.FinishPoly();
                    
                }



            }





            this._geoMapFrame.Parent.Invalidate();




        }



        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this._mode != FSimpleGemotryEditMode.POINT)
            {
                //需要绘制 最后一个点

                if (this._coordsInner.Count > 0)
                {

                   


                    //这里我们应该采用局部重绘技术，否则在大图像下刷新率将会急剧下降，目前已经遭受过此问题

                    //这里采用局部刷新技术，哈哈


                    Coordinate coordLast = this._coordsInner[this._coordsInner.Count - 1];

                    Point ptLast = this._geoMapFrame.ProjToBuffer(coordLast);

         
                    Rectangle oldRect = StyleGlobal.GetRectangle(_mousePosition, ptLast);
                    Rectangle newRect = StyleGlobal.GetRectangle(e.Location, ptLast);
                    Rectangle invalid = Rectangle.Union(newRect, oldRect);




                    //这里需要分别考虑是线，还是多边形，目前多边形算法多了一条边，郁闷了

                    if (this._mode==FSimpleGemotryEditMode.POLY)
                    {

                        Coordinate coordFirst = this._coordsInner[0];

                        Point ptFirst = this._geoMapFrame.ProjToBuffer(coordFirst);


                        Rectangle oldRectFirst = StyleGlobal.GetRectangle(_mousePosition, ptFirst);
                        Rectangle newRectFisrt = StyleGlobal.GetRectangle(e.Location, ptFirst);

                        
                        //多出来的重绘区域

                        invalid = Rectangle.Union(newRectFisrt,invalid);
                        invalid = Rectangle.Union(oldRectFirst, invalid);

                        
                    }


                    invalid.Inflate(20, 20);



                    this._geoMapFrame.Parent.Invalidate(invalid);




                   


                    //最后重新赋值，哈哈

                    this._mousePosition = e.Location;



                }

            }


        }



        protected override void OnDraw(FMapDrawArgs e)
        {

            if (this._mode == FSimpleGemotryEditMode.LINE)
            {



                //更换坐标与存储

                this._pts.Clear();


                if (this._coordsInner.Count > 0)
                {





                    foreach (Coordinate c in this._coordsInner)
                    {
                        this._pts.Add(this._geoMapFrame.ProjToBuffer(c));

                    }


                }

                if (this._pts.Count > 0)
                {
                  



                    //先绘制固定线条

                    if (this._pts.Count > 1)
                    {
                        e.Graphics.DrawLines(Pens.DodgerBlue, this._pts.ToArray());

                    }

                    //然后绘制活动线条



                    e.Graphics.DrawLine(Pens.DodgerBlue, this._pts[this._pts.Count - 1], this._mousePosition);










                }


            }


            if (this._mode==FSimpleGemotryEditMode.POLY)
            {

                //更换坐标与存储

                this._pts.Clear();


                if (this._coordsInner.Count > 0)
                {





                    foreach (Coordinate c in this._coordsInner)
                    {
                        this._pts.Add(this._geoMapFrame.ProjToBuffer(c));

                    }


                }

                if (this._pts.Count > 0)
                {




                    //先绘制固定线条

                    if (this._pts.Count > 1)
                    {
                        e.Graphics.DrawLines(Pens.DodgerBlue, this._pts.ToArray());

                    }

                    //然后绘制活动线条



                    e.Graphics.DrawLine(Pens.DodgerBlue, this._pts[this._pts.Count - 1], this._mousePosition);




                    //对于多边形，需要额外绘制起始点

                    e.Graphics.DrawLine(Pens.DodgerBlue, this._mousePosition, this._pts[0]);








                }
                
            }

           


            base.OnDraw(e);


        }

     


        protected void FinishLine()
        {

            this._coordinates.Clear();


            this._coordinates.AddRange(this._coordsInner);



            this._coordsInner.Clear();



            //至少存在两个点，才能构成一条直线

            if (this._coordinates.Count>1)
            {

                this.AddGeomotry();
                
            }


           


        }

        protected void FinishPoly()
        {

            this._coordinates.Clear();


            this._coordinates.AddRange(this._coordsInner);



            this._coordsInner.Clear();







            this.AddGeomotry();


        }


        protected void AddGeomotry()
        {


            if (this.AskAddGeometry != null)
            {
                this.AskAddGeometry(this, EventArgs.Empty);

            }



        }



    }
}
